package config

import (
	"context"
	"fmt"
	"log"
	"os"
	"strconv"
	"time"

	"github.com/redis/go-redis/v9"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
)

var DB *gorm.DB

// Redis 实例
var Rdb *redis.Client

type DBConfig struct {
	User     string
	Password string
	Host     string
	Name     string
	Prefix   string
}

func LoadDBConfig() DBConfig {
	return DBConfig{
		User:     os.Getenv("DB_USER"),
		Password: os.Getenv("DB_PASSWORD"),
		Host:     os.Getenv("DB_HOST"),
		Name:     os.Getenv("DB_NAME"),
		Prefix:   os.Getenv("DB_PREFIX"),
	}
}

// 初始化数据库
func InitDB() error {

	var err error

	config := LoadDBConfig()

	// 数据库连接
	dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		config.User, config.Password, config.Host, config.Name)

	DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			TablePrefix:   config.Prefix, // 设置表前缀
			SingularTable: false,         // 禁用表名复数
		},
	})

	if err != nil {
		log.Fatal("数据库连接失败: ", err)
		return err
	}

	// 本项目不需要自动创建表结构
	// DB.AutoMigrate(&User{}) // 自动迁移数据库结构
	return nil
}

// 初始化Redis
func InitRedis() {

	db, err := strconv.Atoi(os.Getenv("RDS_DATABASE"))
	if err != nil {
		log.Fatal("Redis初始化失败,DB Error:", err)
		return
	}

	Rdb = redis.NewClient(&redis.Options{
		Addr:     os.Getenv("RDS_HOST") + ":" + os.Getenv("RDS_PORT"), // Redis 地址
		Password: os.Getenv("RDS_PASSWORD"),                           // Redis 密码
		DB:       db,                                                  // Redis 数据库
	})

	// 测试连接
	ctx := context.Background()
	if _, err := Rdb.Ping(ctx).Result(); err != nil {
		log.Fatalf("Failed to connect to Redis: %v", err)
		return
	}

	log.Println("Redis 连接成功")

}

// Set 设置缓存
func Set(key string, value interface{}, expiration time.Duration) error {
	ctx := context.Background()
	return Rdb.Set(ctx, key, value, expiration).Err()
}

// Get 获取缓存
func Get(key string) (string, error) {
	ctx := context.Background()
	return Rdb.Get(ctx, key).Result()
}

// Del 删除缓存
func Del(keys ...string) error {
	ctx := context.Background()
	return Rdb.Del(ctx, keys...).Err()
}

// 关闭数据库连接
func CloseDB() {

	mysqldb, _ := DB.DB()

	if err := mysqldb.Close(); err != nil {
		log.Println("关闭数据库连接失败:", err)
	} else {
		log.Println("数据库连接已关闭")
	}
}
